package com.nian.global.service.impl;


import com.nian.global.dao.IDao;
import com.nian.global.utils.BeanUtils;
import com.nian.global.utils.CollectionUtils;
import com.nian.global.utils.ConstantUtils;
import org.apache.commons.beanutils.ConversionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * 设置抽象类，实现基本的增删改查，避免重复开发
 *
 * 遇到特殊的增删改查可在各自的service中单独实现
 * 
 * Created by nian on 2024/1/4.
 */
public abstract class AbstractService<T, K> {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractService.class);

    /** 泛型类型缓存 */
    private final Class<T> voClass;
    private final Class<K> domainClass;

    public AbstractService() {
        Type superClass = getClass().getGenericSuperclass();
        if (!(superClass instanceof ParameterizedType)) {
            throw new IllegalArgumentException("子类必须指定泛型参数");
        }
        ParameterizedType parameterizedType = (ParameterizedType) superClass;
        Type[] types = parameterizedType.getActualTypeArguments();
        this.voClass = (Class<T>) types[0];
        this.domainClass = (Class<K>) types[1];
    }

    /** 子类需提供具体DAO实例 */
    protected abstract IDao<K> iDao();

    /** 添加 */
    public int add(List<T> voList) {

        if (CollectionUtils.isNullOrEmpty(voList)) {
            LOG.info("要添加的数据为空，不能添加！");
            return ConstantUtils.FAIL;
        }

        try {
            List<K> domains = BeanUtils.copyAs(voList, domainClass);
            iDao().add(domains);
            return ConstantUtils.SUCCESS;
        } catch (Exception e) {
            LOG.error("添加数据失败！", e);
            return ConstantUtils.ERROR;
        }
    }

    /** 删除 */
    public int delete(Long[] ids) {

        try {
            iDao().delete(ids);
            return ConstantUtils.SUCCESS;
        } catch (Exception e) {
            LOG.error("删除数据失败！", e);
            return ConstantUtils.ERROR;
        }
    }

    /** 全部删除 */
    public int deleteAll() {

        try {
            iDao().deleteAll();
            return ConstantUtils.SUCCESS;
        } catch (Exception e) {
            LOG.error("删除全部数据失败！", e);
            return ConstantUtils.ERROR;
        }
    }

    /** 更新 */
    public int update(T vo) {

        K k = BeanUtils.copyAs(vo, domainClass);
        try {
            iDao().update(k);
            return ConstantUtils.SUCCESS;
        } catch (Exception e) {
            LOG.error("更新数据失败！", e);
            return ConstantUtils.ERROR;
        }
    }

    /** 根据id查询 */
    public List<T> queryByIds(Long[] ids) {

        List<K> domainList = iDao().queryByIds(ids);
        if (CollectionUtils.isNullOrEmpty(domainList)) {
            return null;
        }
        return BeanUtils.copyAs(domainList, voClass);
    }

    /** 根据条件查询 */
    public List<T> query(T vo) {

        K domain = BeanUtils.copyAs(vo, domainClass);
        List<K> domainList = iDao().query(domain);
        if (CollectionUtils.isNullOrEmpty(domainList)) {
            return null;
        }
        return BeanUtils.copyAs(domainList, voClass);
    }

}
